#ifndef GESTAO_H_
#define GESTAO_H_

#include <iostream>
#include <sstream>
#include <fstream>

#include <vector>
#include <string>

typedef unsigned int uint;
typedef unsigned long ulong;

using namespace std;

class Alimento {
protected:
	string(erro);

	static uint numAlimento;
	uint ID;

	string nome;
	float calorias;

public:
	Alimento(string nome, float calorias);
	~Alimento();

	uint getID() const;
	string getNome() const;
	float getCalorias() const;

	bool operator ==(Alimento alimento) const;
};

class Epoca {
protected:
	uint epocaInicial;
	uint epocaFinal;

public:
	Epoca(uint epocaInicial, uint epocaFinal);
	~Epoca();

	uint getEpocaInicial() const;
	uint getEpocaFinal() const;
};

class Peixe: public Alimento {
	vector<Alimento> peixes;

public:
	Peixe(string nome, float calorias);
	~Peixe();
};

class Magro: public Peixe{
public:
	Magro(string nome, float calorias);
	~Magro();
};

class MeioGordo: public Peixe {
public:
	MeioGordo(string nome, float calorias);
	~MeioGordo();
};

class Gordo: public Peixe {
public:
	Gordo(string nome, float calorias);
	~Gordo();
};

class Carne: public Alimento {
public:
	Carne(string nome, float calorias);
	~Carne();
};

class Caca: public Carne {
protected:
	vector<Alimento> carnesCaca;

public:
	Caca(string nome, float calorias);
	~Caca();
};

class Ave: public Carne {
protected:
	vector<Alimento> carnesAve;

public:
	Ave(string nome, float calorias);
	~Ave();
};

class Bovino: public Carne {
protected:
	vector<Alimento> carnesBovino;

public:
	Bovino(string nome, float calorias);
	~Bovino();
};

class Vegetal: public Alimento, public Epoca {
	vector<Alimento> vegetais;

public:
	Vegetal(string nome, float calorias, uint epocaInicial, uint epocaFinal);
	~Vegetal();

	//void loadVegetais();
};

class Fruta: public Alimento, public Epoca {
	vector<Alimento> frutas;

public:
	Fruta(string nome, float calorias, uint epocaInicial, uint epocaFinal);
	~Fruta();

	//void loadFrutas();
};

class Dieta {

	vector<Alimento> segunda;
	vector<Alimento> terca;
	vector<Alimento> quarta;
	vector<Alimento> quinta;
	vector<Alimento> sexta;
	vector<Alimento> sabado;
	vector<Alimento> domingo;

	float caloriasMaximas;

public:
	Dieta(float caloriasMaximas);
	~Dieta();

	float getCaloriasMaximas() const;
	void setCaloriasMaximas(float calorias);
	void adicionaPA(Alimento x, vector<Alimento> dia);

	bool ePossivel() const;

	void adicionaAlimento(Alimento alimento);

};

class Cliente {
	string nome;
	uint idade;
	char sexo;
	float peso;
	float altura;
	float IMC;
	float calKg; // calorias por quilograma
	uint nRefeicoes;
	bool diabetes;
	vector<Alimento> alergias;
	vector<vector<vector <Alimento> > >  dieta;


	//estado do cliente
	bool magreza;
	bool saudavel;
	bool pesoExcesso;
	bool obesidade; 			// grau 1
	bool obesidadeSevera; 		// grau 2
	bool obesidadeMorbida; 		// grau 3*

public:
	Cliente(string nome, uint idade, char sexo, float peso, float altura);
	~Cliente();

	string getNome() const;
	uint getIdade() const;
	char getSexo() const;
	float getPeso() const;
	float getAltura() const;
	uint getNRefeicoes() const;
	vector<vector<vector <Alimento> > > getDieta() const;
	vector<Alimento> getAlergias() const;
	bool getDiabetes() const;
	uint calculaCalorias(uint dia);

	bool eDiabetico() const;
	bool eAlergico(Alimento x);


	void setNome(string nome);
	void setIdade(uint idade);
	void setSexo(char sexo);
	void setPeso(float peso);
	void setAltura(float altura);
	void setNRefeicoes(uint nRefeicoes);
	bool setAlergia(Alimento x);
	void setDiabetes();

	void adicionaAlergia(Alimento x);
	void adicionaPAlmoco(Alimento x, uint dia);
	void adicionaAlmoco(Alimento x, uint dia);
	void adicionaJantar(Alimento x, uint dia);
	void adicionaRefExtra(Alimento x, uint dia);

	void listaAlimentos();
	void removeAlimento(uint ali);


	float calculaIMC();
	//float calculaCalKg();

	bool operator == (Cliente cliente) const;
};

class Gestao {
	uint dia;
	uint mes;
	ulong ano;
	vector<Cliente> clientes;
	vector<Carne> carnes;
	vector<Peixe> peixes;
	vector<Vegetal> vegetais;
	vector<Fruta> frutas;

public:
	uint getDia() const;
	uint getMes() const;
	ulong getAno() const;

	void setDia(uint dia);
	void setMes(uint mes);
	void setAno(ulong ano);

	vector<Cliente> getClientes() const;
	vector<Carne> getCarnes() const;
	vector<Peixe> getPeixes() const;
	vector<Vegetal> getVegetais() const;
	vector<Fruta> getFrutas() const;
	uint getNumClientes() const;
	Alimento getAlimentoByID(uint ID) const;

	void setCarnes(vector<Carne> &carnes);
	void setPeixes(vector<Peixe> &peixes);
	void setVegetais(vector<Vegetal> &vegetais);
	void setFrutas(vector<Fruta> &frutas);

	void EditarNome(string nome, uint cli);
	void EditarIdade(uint idd, uint cli);
	void EditarSexo(char x, uint cli);
	void EditarPeso(float peso, uint cli);
	void EditarAltura(float alt, uint cli);


	uint mesDieta();
	bool adicionaCliente(Cliente c1);
	bool removeCliente(Cliente c1);
	void listaAlimentos();
	void listaClientes();
	void fazDieta(Cliente c);
	void fazDieta(uint cli);

	void loadClientes();
	void saveClientes();
	void loadAlimentos();
};

#endif /* GESTAO_H_ */
